package com.boil.qz.safekavass.shiro.filter;

import com.boil.model.MenuInfo;
import com.boil.pojo.ResultVo;
import com.boil.qz.safekavass.model.LoginUser;
import com.boil.qz.safekavass.service.LoginUserService;
import com.boil.qz.safekavass.websocket.WebSocketTextServer;
import com.boil.util.Constants;
import com.boil.util.MenuUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Created by ChenYong on 2017-05-03.
 * <br>
 * 登录表单认证过滤器。
 */
public class LoginFormAuthenticationFilter extends FormAuthenticationFilter {
    /**
     * 日志
     */
    protected static Logger log = LoggerFactory.getLogger(LoginFormAuthenticationFilter.class);
    /**
     * 注入用户 Service
     */
    @Autowired
    private LoginUserService loginUserService;
    /**
     * 注入 WebSocket 文本服务器
     */
    @Autowired
    private WebSocketTextServer webSocketTextServer;

    /**
     * 登录成功。
     *
     * @param token    令牌
     * @param subject  用户
     * @param request  请求
     * @param response 响应
     * @return 是否登录成功：
     * <li>
     * <ol>true-是；</ol>
     * <ol>false-否。</ol>
     * </li>
     * @throws Exception 抛出异常
     */
    @Override
    protected boolean onLoginSuccess(AuthenticationToken token, //
                                     Subject subject, //
                                     ServletRequest request, //
                                     ServletResponse response) throws Exception {
        // 登录 Token
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        // 获取 Session
        Session session = subject.getSession();
        // 获取登录账号
        String account = usernamePasswordToken.getUsername();
        // 获取登录用户的信息
        LoginUser loginUser = loginUserService.findAdminByLoingid(account);

        // 将用户信息存入 Session 中
        session.setAttribute(Constants.LOGIN_USER, loginUser);

        // 获取所有菜单
        List<MenuInfo> menuInfos = MenuUtils.getLoginUserMenus();
        // 被控制权限菜单
        List<MenuInfo> menuInfos1 = new ArrayList<MenuInfo>();

        // 菜单权限控制
        // 廖昆拥有【举报情况】、【用户管理】菜单权限
        if ("qzlkun".equals(loginUser.getLoginid())) {
            for (int i = 0; i < menuInfos.size(); i++) {
                MenuInfo menuInfo = menuInfos.get(i);

                if ("举报情况".equals(menuInfo.getName())) {
                    menuInfos1.add(menuInfo);
                } else if ("用户管理".equals(menuInfo.getName())) {
                    Iterator<MenuInfo> iterator = menuInfo.getChilds().iterator();

                    while (iterator.hasNext()) {
                        MenuInfo menuInfo1 = iterator.next();

                        if ("用户列表".equals(menuInfo1.getName())) {
                            iterator.remove();
                        }
                    }

                    menuInfos1.add(menuInfo);
                }
            }

            // 谢仕强，陈浪，陈勇，周兵拥有除【举报情况】以外的菜单权限
        } else if ("qzxsq".equals(loginUser.getLoginid()) ||
                "chenlang".equals(loginUser.getLoginid()) ||
                "chenyong".equals(loginUser.getLoginid()) ||
                "zhoub".equals(loginUser.getLoginid())) {
            for (int i = 0; i < menuInfos.size(); i++) {
                MenuInfo menuInfo = menuInfos.get(i);

                if (!"举报情况".equals(menuInfo.getName())) {
                    menuInfos1.add(menuInfo);
                }
            }

            // 超级管理员，拥有所有菜单的权限
        } else if ("administrator".equals(loginUser.getLoginid())) {
            menuInfos1 = menuInfos;
        }

        // 将登录用户的所有菜单存入 session 中
        session.setAttribute(Constants.LOGIN_USER_MENUS, menuInfos1);

        Constants.ONLINE_SESSION_ID_LIST.add((String) session.getId());

        // 结果映射
        ResultVo onlineSessionCountResultVo = new ResultVo();

        onlineSessionCountResultVo.setResultCode(Constants.ONLINE_SESSION_COUNT);
        onlineSessionCountResultVo.setResultMsg(Constants.ONLINE_SESSION_COUNT_MSG);
        onlineSessionCountResultVo.setResult(Constants.ONLINE_SESSION_ID_LIST.size());

        // 告诉所有客户端，有人登录啦
        webSocketTextServer.sendMessage(onlineSessionCountResultVo);

        log.info("账号：{}--->登录成功", account);

        return super.onLoginSuccess(usernamePasswordToken, subject, request, response);
    }
}